/*
 * time_probe.h
 *
 *  Created on: 2008-9-8
 *      Author: fanliangliang
 */

#ifndef TIME_PROBE_H_
#define TIME_PROBE_H_

#include "config.h"
#include <ctime>
#include <map>
#include <string>
#include <iostream>

BEGIN_NAMESPACE_TOXIC

using std::map;
using std::string;
using std::ostream;
using std::cout;

namespace detail {

	class Timestamp {
	public:
		Timestamp(clock_t tick, time_t second, short millisecond);
		Timestamp();
		~Timestamp();

		Timestamp& operator-= (const Timestamp& rhs);
		Timestamp& operator+= (const Timestamp& rhs);

		static Timestamp startTime();
		static Timestamp endTime();

	public:
		clock_t ticks;
		time_t seconds;
		short milliseconds;
	};

	inline Timestamp operator-(const Timestamp& lhs, const Timestamp& rhs) {
		Timestamp result(lhs);
		return result -= rhs;
	}

	inline Timestamp operator+(const Timestamp& lhs, const Timestamp& rhs) {
		Timestamp result(lhs);
		return result += rhs;
	}

	inline bool operator<(const Timestamp& lhs, const Timestamp& rhs) {
		if (lhs.seconds != rhs.seconds) {
			return lhs.seconds < rhs.seconds;
		}
		else {
			return lhs.milliseconds < rhs.milliseconds;
		}
	}

	inline bool operator>(const Timestamp& lhs, const Timestamp& rhs) {
		return rhs < lhs;
	}



	class TimeHolder {
		typedef map<string, Timestamp*> ItemTimestampMap;
	public:
		TimeHolder();
		~TimeHolder();

		void increaseTime(const string& item, const Timestamp& ts);
		void report(ostream& ostrm) const;
		void clear();

	private:
		ItemTimestampMap _map;
	};

} // namespace detail


class TimeProbe {
public:
	TimeProbe(const string& item, bool autoProbe = true);
	~TimeProbe();

	void stop();

	static void report(ostream& ostrm = cout);
	static void clear();

private:
	static detail::TimeHolder _timeHolder;

private:
	string _item;
	bool _autoProbe;
	detail::Timestamp _startTime;
};

END_NAMESPACE_TOXIC

#endif /* TIME_PROBE_H_ */
